﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace BPMS.Utility.RegexExpress
{
    public class RegexUtility
    {
        /// <summary>
        /// 是否包含中文或全角字符
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static bool IsHasChinese(string source)
        {
            if (string.IsNullOrEmpty(source)) return false;
            ASCIIEncoding n = new ASCIIEncoding();
            byte[] b = n.GetBytes(source);
            for (int i = 0; i <= b.Length - 1; i++)
                if (b[i] == 63) return true;  //判断是否(T)为汉字或全脚符号 
            return false;
        }

        /// <summary>
        /// 包含html
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static bool IsHasHtml(string source)
        {
            return !string.IsNullOrEmpty(source) && Regex.IsMatch(source, @"<|>", RegexOptions.Compiled);
        }

        /// <summary>
        /// 判断是否是正确的身份证编码格式
        /// </summary>
        /// <param name="source"></param>
        /// <param name="mesage"></param>
        /// <returns></returns>
        public static bool IsIDCard(string source, out string mesage)
        {
            mesage = "身份证长度不对";
            if (string.IsNullOrEmpty(source))
                return false;
            if (source.Length == 18)
                return IsIDCard18(source, out mesage);
            return source.Length == 15 && IsIDCard15(source, out mesage);
        }

        /// <summary>
        /// 是否为18位身份证号码
        /// </summary>
        /// <param name="Id"></param>
        /// <param name="mesage"></param>
        /// <returns></returns>
        public static bool IsIDCard18(string Id, out string mesage)
        {
            long n;
            if (long.TryParse(Id.Remove(17), out n) == false || n < Math.Pow(10, 16) || long.TryParse(Id.Replace('x', '0').Replace('X', '0'), out n) == false)
            {
                mesage = "不是有效的身份证号";
                return false;//数字验证
            }
            const string address = "11x22x35x44x53x12x23x36x45x54x13x31x37x46x61x14x32x41x50x62x15x33x42x51x63x21x34x43x52x64x65x71x81x82x91";
            if (address.IndexOf(Id.Remove(2)) == -1)
            {
                mesage = "省份不合法";
                return false;//省份验证
            }
            string birth = Id.Substring(6, 8).Insert(6, "-").Insert(4, "-");
            DateTime time;
            if (DateTime.TryParse(birth, out time) == false)
            {
                mesage = "生日不合法";
                return false;//生日验证
            }
            string[] arrVarifyCode = ("1,0,x,9,8,7,6,5,4,3,2").Split(',');
            string[] wi = ("7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2").Split(',');
            char[] ai = Id.Remove(17).ToCharArray();
            int sum = 0;
            for (int i = 0; i < 17; i++)
            {
                sum += int.Parse(wi[i]) * int.Parse(ai[i].ToString());
            }
            int y;
            Math.DivRem(sum, 11, out y);
            if (arrVarifyCode[y] != Id.Substring(17, 1).ToLower())
            {
                mesage = "不是有效的身份证号";
                return false;//校验码验证
            }
            mesage = "正确";
            return true;//符合GB11643-1999标准
        }

        /// <summary>
        /// 是否为15位身份证号码
        /// </summary>
        /// <param name="Id"></param>
        /// <param name="mesage"></param>
        /// <returns></returns>
        public static bool IsIDCard15(string Id, out string mesage)
        {
            long n;
            if (long.TryParse(Id, out n) == false || n < Math.Pow(10, 14))
            {
                mesage = "不是有效的身份证号";
                return false;//数字验证
            }
            const string address = "11x22x35x44x53x12x23x36x45x54x13x31x37x46x61x14x32x41x50x62x15x33x42x51x63x21x34x43x52x64x65x71x81x82x91";
            if (address.IndexOf(Id.Remove(2)) == -1)
            {
                mesage = "省份不合法";
                return false;//省份验证
            }
            string birth = Id.Substring(6, 6).Insert(4, "-").Insert(2, "-");
            DateTime time;
            if (DateTime.TryParse(birth, out time) == false)
            {
                mesage = "生日不合法";
                return false;//生日验证
            }
            mesage = "正确";
            return true;//符合15位身份证标准
        }

        /// <summary>
        /// 是否为时间格式
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static bool IsDateTime(string source)
        {
            if (string.IsNullOrEmpty(source))
                return false;
            return Regex.IsMatch(source, @"^[ ]*[012 ]?[0123456789]?[0123456789]{2}[ ]*[-]{1}[ ]*[01]?[0123456789]{1}[ ]*[-]{1}[ ]*[0123]?[0123456789]"
                + @"{1}[ ]*[012]?[0123456789]{1}[ ]*[:]{1}[ ]*[012345]?[0123456789]{1}[ ]*[:]{1}[ ]*[012345]?[0123456789]{1}[ ]*$", RegexOptions.Compiled);
        }


        /// <summary>
        /// 判断是否是XML 1.0允许的字符
        /// </summary>
        /// <param name="character"></param>
        /// <returns></returns>
        private static bool IsLegalXmlChar(int character)
        {
            return
            (
                 character == 0x9 /* == '\t' == 9   */        ||
                 character == 0xA /* == '\n' == 10  */        ||
                 character == 0xD /* == '\r' == 13  */        ||
                (character >= 0x20 && character <= 0xD7FF) ||
                (character >= 0xE000 && character <= 0xFFFD) ||
                (character >= 0x10000 && character <= 0x10FFFF)
            );
        }

        /// <summary>
        /// 判断是否是合法的 XML 1.0标准允许的字符串 true：标准 false：包含不标准的字符
        /// </summary>
        /// <param name="xml"></param>
        /// <returns></returns>
        public static bool IsLegalXmlChar(string xml)
        {
            return string.IsNullOrEmpty(xml) || xml.All(c => IsLegalXmlChar(c));
        }

        /// <summary>
        /// 是否匹配
        /// </summary>
        /// <param name="source"></param>
        /// <param name="pattern"></param>
        /// <returns></returns>
        public static bool IsMatch(string source, string pattern)
        {
            return Regex.IsMatch(source, pattern, RegexOptions.IgnoreCase);
        }
    }
}
